#pragma once
#include <string>
#include <vector>
#include <cstring>

namespace ns_protocol
{
// 用于标定一个完整的数据,解决粘包问题
#define SEP "X"
#define SEP_SIZE strlen(SEP)

// 用于序列化分割数据段
#define SPACE " "
#define SPACE_SIZE strlen(SPACE)

    void Splite(std::string &instr, std::vector<std::string> *vStr)
    {
        while (true)
        {
            auto pos = instr.find(SEP);
            if (std::string::npos == pos)
            {
                break;
            }

            vStr->push_back(instr.substr(0, pos)); // 将切割好的request添加到vStr中
            instr.erase(0, pos + 1);               // 覆盖掉已经提取到的request
        }
        // size_t pos=0;
        // while(true)
        // {
        //     auto rpos=instr.find(SEP,pos);
        //     if(std::string::npos==rpos)
        //     {
        //         break;
        //     }
        //     vStr->push_back(instr.substr(pos,rpos-pos));
        //     pos=rpos+SEP_SIZE;
        // }
        // instr.erase(0,pos);
    }

    void EnCode(std::string &str)
    {
        str+=SEP;
    }

    // 请求
    class Request
    {
    public:
        char _op;
        int _x;
        int _y;

    public:
        Request() = default;
        ~Request() = default;

        Request(const char &op, const int &x, const int &y)
            : _op(op), _x(x), _y(y)
        {
        }

        // xopy 序列化 x op y
        std::string Serialization()
        {
            std::string str;

            str += std::to_string(_x);
            str += SPACE;
            str += _op;
            str += SPACE;
            str += std::to_string(_y);

            return str;
        }

        // 反序列化
        bool Deserialization(const std::string &str)
        {
            std::size_t left = str.find(SPACE);
            if (left == std::string::npos)
            {
                return false;
            }

            std::size_t right = str.rfind(SPACE);
            if (right == std::string::npos)
            {
                return false;
            }

            _x = atoi(str.substr(0, left).c_str());
            _y = atoi(str.substr(right + SPACE_SIZE).c_str());
            _op = str[left + SPACE_SIZE];

            return true;
        }
    };

    // 响应
    class Response
    {
    public:
        int _result;
        int _code;

    public:
        Response() = default;
        ~Response() = default;

        Response(const int &result, const int &code) : _result(result), _code(code)
        {
        }

        // coderesult 序列化 code result
        std::string Serialization()
        {
            std::string str;
            str += std::to_string(_code);
            str += SPACE;
            str += std::to_string(_result);

            return str;
        }

        // 反序列化
        bool Deserialization(const std::string &str)
        {
            std::size_t pos = str.find(SPACE);
            if (pos == std::string::npos)
            {
                return false;
            }
            _code = atoi(str.substr(0, pos).c_str());
            _result = atoi(str.substr(pos + SPACE_SIZE).c_str());

            return true;
        }
    };

}
